package com.studerb.tests.nntp;

import static org.junit.Assert.*;

import java.io.IOException;
import javax.swing.JOptionPane;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.StopWatch;

import com.studerb.model.Server;
import com.studerb.service.*;
import com.studerb.nntp.NntpConnection;

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:testContext.xml" }) public class TestGoodNetwork
implements ApplicationContextAware {
	@Autowired static SettingsService settingsService; 
	private GenericApplicationContext appContext;
	Server goodAuthServer;
	Server badHostServer;
	Server badAuthServer;
	static int timeout;
	static StopWatch stopWatch;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		settingsService.start();
		timeout = Integer.parseInt(settingsService.getSetting("TimeoutSocketFactory.timeout"));
		stopWatch = new StopWatch();
		JOptionPane.showMessageDialog(null, "Make sure the network is ON");
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {}


	@Before
	public void setUp() throws Exception {
		goodAuthServer = new Server("news.giganews.com", new Integer(119), new Integer(9),
				"gn115371", "n!iC3n", true, true);
		badHostServer = (Server) goodAuthServer.clone();
		badHostServer.setHost("some.bad.host");
		badAuthServer = (Server) goodAuthServer.clone();
		badAuthServer.setPassword("badpass");
	}

	@After
	public void tearDown() throws Exception {
		goodAuthServer = null;
		badHostServer = null;
		badAuthServer = null;
	}

	@Test
	public void testConnectionGood() {
		NntpConnection nntpConnection = (NntpConnection) appContext.getBean("nntpConnection");
		nntpConnection.setServer(goodAuthServer);
		try {
			nntpConnection.connect();
		} catch (IOException e) {
			e.printStackTrace();
			fail("Shouldn't have caught exception: " + e.getMessage());
		} finally {
			nntpConnection.disconnect();
		}
	}

	@Test
	public void testConnectionBadHost() {
		NntpConnection nntpConnection = (NntpConnection) appContext.getBean("nntpConnection");
		nntpConnection.setServer(badHostServer);
		try {
			stopWatch.start();
			nntpConnection.connect();
			fail("Should have thrown exception because of badhost");
		} catch (IOException e) {
			stopWatch.stop();
			//We should have got a bad server exception long before timing out
			if ((stopWatch.getTotalTimeMillis()) > timeout)
				fail("should have failed long before timeout");
		} finally {
			nntpConnection.disconnect();
		}

	}

	@Test
	public void testConnectionBadAuth() {
		NntpConnection nntpConnection = (NntpConnection) appContext.getBean("nntpConnection");
		nntpConnection.setServer(badAuthServer);
		try {
			stopWatch.start();
			nntpConnection.connect();
			fail("Should have thrown exception with testConnection with Server set with bad address");
		} catch (IOException e) {
			stopWatch.stop();
			//We should have got a bad server exception long before timing out
			if ((stopWatch.getTotalTimeMillis()) > timeout)
				fail("should have failed long before timeout");
		} finally {
			nntpConnection.disconnect();
		}

	}

	@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.appContext = (GenericApplicationContext) applicationContext;
	}
}